<!--
  2025.05.19 nijs 参考地址：https://www.cnblogs.com/Ning-Blog/p/17592900.html
  https://github.com/dream-num/Luckysheet
-->
<template>
  <div>
    <div ref="canvas" id="luckysheet" class="luckysheet-content">
      <input type="hidden" id="download-excel" @click="downloadExcel"/>
    </div>
  </div>
</template>

<script>
import Vue from "vue";
import {ACCESS_TOKEN} from "@/store";
import XLSX from 'xlsx-js-style';
import ExcelJS from 'exceljs';
import JSZip from "jszip";

export default {
  name: "Luckysheet",
  props: {
    /* 编辑器的内容 */
    value: {
      type: String,
    },
    /* excel名称 */
    title: {
      type: String,
      default: "",
    },
    /* 是否允许编辑 */
    allowEdit: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      luckysheet: null,
      fileDownloadUrl:'',
      fileName:'',
      canDownload:true,
      canPrint:true,
      options: {
        container: 'luckysheet', //容器id名
        title: this.title, // 表 头名
        lang: 'zh', // 中文
        allowEdit:this.allowEdit,// 是否可编辑
        showtoolbar: true, // 是否显示工具栏
        showinfobar: false, // 是否显示顶部信息栏
        showsheetbar: true, // 是否显示底部sheet按钮
        forceCalculation: false,//强制刷新公式
        showtoolbarConfig: ['print','download'],
        data:[],
      },
      sheetImages:[],
      sheetParams: [
        {
          name: "sheet1",
          color: "",
          index: 1,
          status: 0,
          order: 1,
          celldata: [],
          config: {},
        },
      ],
    };
  },
  created() {},
  mounted() {
    // var initData = this.value?JSON.parse(this.value):this.sheetParams
    this.initLuckysheet();// initData
  },
  methods: {
    downloadExcel(){
      console.log("downloadExcel")
      // window.open(this.fileDownloadUrl);
      fetch(this.fileDownloadUrl)
          .then(response => response.blob())
          .then(blob => {
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = this.fileName;
            document.body.appendChild(a);
            a.click();
            window.URL.revokeObjectURL(url);
          });
    },
    async initLuckysheet() {
      const toBoolean = val => {
        if (typeof val === 'string') {
          return val.toLowerCase() === 'true'
        }
        return !!val
      }

      const file = {
        id: this.$route.query.id,
        mime: this.$route.query.mime,
        name: this.$route.query.name,
        print0: this.$route.query.print || true,
        download: this.$route.query.download || false,
        isAutoPrint:this.$route.query.isAutoPrint,
        printDebug: toBoolean(this.$route.query.printDebug) || false,
        printAutoFontSize: toBoolean(this.$route.query.printAutoFontSize) || false,
      }

      this.fileName = file.name?file.name:'filename.xlsx'

      // 2025.06.06 nijs 暂时只有xlsx格式文件
      document.title = this.fileName.replaceAll(".xlsx","");

      this.$set(this, 'canDownload', toBoolean(file.download))
      this.$set(this, 'canPrint', toBoolean(file.print0))

      if (file.id) {
        // 获取后缀
        let token = Vue.ls.get(ACCESS_TOKEN)
        if(!token){
          token = this.$route.query.token
        }
        this.fileDownloadUrl = Global.VUE_APP_BIZ_API_FILEMANAGER_URL + '/admin/fileManager/download?id=' + file.id + '&access_token=' + token

        window.luckysheet.destroy();

        let imgs = [];
        let cellImgs = [];// 单元格插入的图片
        let initImgIndexs = [0];
        let initCellImgIndexs = [0];
        try{
          const response = await fetch(this.fileDownloadUrl);
          const buffer = await response.arrayBuffer();
          // 解析单元格中图片信息
          const jszip = new JSZip();
          const zip = await jszip.loadAsync(buffer);

          const workbook = XLSX.read(buffer, {
            type: 'array',
            cellStyles: true,// 明确要求保留样式 单元格宽高
          });
          const workbookStyle = new ExcelJS.Workbook();
          await workbookStyle.xlsx.load(buffer);
          cellImgs = await this.loadCellImgs(zip)
          imgs = await this.loadImgs(workbook,workbookStyle,zip)
          this.options.data = await this.loadExcelWithStyles(workbook,workbookStyle);
          this.options.image = imgs
          // console.log("nijsLog56:",imgs)
        } catch (error) {
          console.error('加载 Excel 文件失败:', error);
          alert('预览文件不存在，或被加密不可读取');
        }

        let showtoolbarConfig = []
        if(toBoolean(file.print0)){
          showtoolbarConfig.push("print")
        }
        if(toBoolean(file.download)){
          showtoolbarConfig.push("download")
        }
        this.options.showtoolbarConfig = showtoolbarConfig
        this.options.printDebug = file.printDebug //  打印调试
        if(file.isAutoPrint=='1'||file.isAutoPrint=='2'){
          this.options.printAutoFontSize = true // 打印模板字体大小自适应
        }else {
          this.options.printAutoFontSize = file.printAutoFontSize // 打印字体大小自适应
        }

        let that = this
        this.options.hook = {
          workbookCreateAfter:function(){
            // 工作簿创建后的钩子函数，自动调用打印方法
            let autoPrint = window.document.getElementById('luckysheet-icon-print')
            if(autoPrint && file.isAutoPrint=='1'){
              let newUrl = window.location.href.replaceAll('&isAutoPrint=1','&isAutoPrint=2'); // 重新构建URL，避免无法查看预览页面
              history.replaceState({}, document.title, newUrl); // 改变当前URL但不重新加载页面
              autoPrint.click()
            }

            // 初始加载第一页的单元格图片
            let sheetImgs = that.sheetImages.find(item=>item.sheet==0)
            // 初始化单元格图片
            if(sheetImgs && sheetImgs.xys.length>0){
              sheetImgs.xys.forEach((img)=>{// 加载图片
                let cellImg = cellImgs.find(item=>img.value.indexOf(item.id)>-1)
                let suffix = cellImg.fileName.substring(cellImg.fileName.lastIndexOf('.')+1)
                let src = cellImg.url// .replace('application/octet-stream','image/'+suffix)
                console.log("nijsLog29:",img,cellImg)
                window.luckysheet.setCellValue(img.r, img.c, {
                  m: `<img src="${src}"/>`,
                  v: img.value,
                  ct: { fa: "General", t: "img" },
                  ht:"0"
                });
              })
            }
          },
          sheetActivate:function (i,isPivotInitial,isNewSheet){
            console.log("sheetActivate:",i,isPivotInitial,isNewSheet)
            // 切换sheet时，初始化图片
            if(imgs.length>0 && i<imgs.length && !initImgIndexs.includes(i)){
              initImgIndexs.push(i)
              imgs[i].forEach((img)=>{
                // 加载图片
                window.luckysheet.insertImage(img.src,img);
              })
            }
            // 加载单元格图片
            let sheetImgs = that.sheetImages.find(item=>item.sheet==i)
            // this.sheetImages
            // 初始化单元格图片
            if(sheetImgs && sheetImgs.xys.length>0 && !initCellImgIndexs.includes(i)){
              initCellImgIndexs.push(i)
              sheetImgs.xys.forEach((img)=>{// 加载图片
                let cellImg = cellImgs.find(item=>img.value.indexOf(item.id)>-1)
                let suffix = cellImg.fileName.substring(cellImg.fileName.lastIndexOf('.')+1)
                let src = cellImg.url  // .replace('application/octet-stream','image/'+suffix)
                // console.log("nijsLog04:",src)
                // console.log("nijsLog29:",img,cellImg)
                setTimeout(function(){
                  // 延迟赋值，保证数据准确
                  window.luckysheet.setCellValue(img.r, img.c, {
                    m: `<img src="${src}"/>`,
                    v: img.value,
                    ct: { fa: "General", t: "img" },
                    ht:"0"
                  });
                },100)
              })
            }
          },
        }

        await window.luckysheet.create(this.options)
        // 初始化图片
        if(imgs.length>0){
          imgs[0].forEach((img)=>{
            // 加载图片
            window.luckysheet.insertImage(img.src,img);
          })
        }

        // console.log("nijsLog37:",img)

        /*var that = this;
        this.$refs.canvas.addEventListener("click", async function(){
          try {
            const xml = await window.luckysheet.getluckysheetfile();
            that.$emit("input",JSON.stringify(xml))
          } catch (error) {
            that.$modal.msgError('实时保存失败'+error)
          }
        })*/
      }
    },
    async loadCellImgs(zip){
      // 检查是否有xl/media目录（存储图片的位置）
      const medias = [];
      zip.folder('xl/media').forEach((relativePath, file) => {
        medias.push(file);
      });
      // 转换为 base64
      let mediaFiles = []
      await Promise.all(
        medias.map(async (file) => {
          const blob = await file.async("blob");
          return new Promise((resolve) => {
            const reader = new FileReader();
            reader.onload = () => {
              resolve({name:file.name, url: reader.result});
            };
            reader.readAsDataURL(blob);
          });
        })
      ).then((res) => {
        mediaFiles = res
        // console.log("nijsLog01:",mediaFiles)
      });

      // 解析全局的drawing关系
      let drawingRels = []
      await this.parseAllDrawingRelationships(zip).then((res) => {
        drawingRels = res
        console.log("nijsLog02:",drawingRels)
      });
      // 解析单元格中图片信息
      const cellImages = await this.parseCellImages(zip, mediaFiles, drawingRels);
      console.log("nijsLog03:",cellImages)
      return cellImages;
    },
    // 加载图片
    async loadImgs(workbook,workbookStyle,zip){
      let imgData = []
      try {
        // 3. 准备 LuckySheet 数据
        imgData = workbook.SheetNames.map((sheetName, index) => {
          const worksheet = workbook.Sheets[sheetName];
          const worksheetStyle = workbookStyle.worksheets[index];
          // const { data, merges, styles} = this.convertExcelToLuckySheet(worksheet,worksheetStyle);
          // 提取图片（ExcelJS 支持获取图片）
          let rstImages = []
          let images = worksheetStyle.getImages()
          for (const image of images) {
            const imageId = image.imageId; // 图片 ID
            const imageRef = workbookStyle.getImage(imageId); // 获取图片引用
            console.log("image:",image.range)

            const { tl, br } = image.range;
            // 获取列宽(单位:字符宽度，默认 8.43 字符 ≈ 64px)
            let imgLeft = 0;
            let totalWidth = image.range.ext?.width || 0;
            // 获取行高(单位:磅)
            let imgTop = 0;
            let totalHeight = image.range.ext?.height || 0;
            // debugger;
            if(br && (br.nativeCol || br.nativeCol==0)){
              for (let col = 0; col <= br.nativeCol; col++) {
                let colWidth = worksheetStyle.columns && worksheetStyle.columns[col]?.width*8 || 72;
                // console.log("colWidth:",col,tl.col,colWidth)
                if(col<tl.nativeCol){// 前置列
                  imgLeft += colWidth
                }else if(col==tl.nativeCol){// 起始列
                  let strWidth = tl.nativeColOff / 914400 * 96
                  // console.log("strWidth:",strWidth)
                  imgLeft += strWidth
                  totalWidth += colWidth - strWidth;
                }else if(col>=br.nativeCol){// 结束列
                  let endWidth = br.nativeColOff / 914400 * 96
                  // console.log("endWidth:",endWidth)
                  totalWidth += endWidth;
                }else{
                  totalWidth += colWidth;
                }
              }
              for (let row = 0; row <= br.nativeRow; row++) {
                if(row > 0 && row%10===0){
                  imgTop += 2// 每十行补偿2px
                }
                // getRow 从1开始
                let rowHeight = worksheetStyle.getRow(row+1)?.height*1.3333 || 20;
                // console.log("rowHeight:",row,rowHeight)
                if(row<tl.nativeRow){// 前置行
                  imgTop += rowHeight
                }else if(row==tl.nativeRow){// 起始行
                  let strHeight = tl.nativeRowOff / 914400 * 96
                  // console.log("strHeight:",strHeight,rowHeight)
                  imgTop += strHeight
                  totalHeight += rowHeight - strHeight;
                }else if(row>=br.nativeRow){// 结束行
                  let endHeight = br.nativeRowOff / 914400 * 96
                  // console.log("endHeight:",endHeight)
                  totalHeight += endHeight;
                }else{
                  totalHeight += rowHeight;
                }
              }
            }else if(tl && (tl.nativeCol||tl.nativeCol==0)){
              for (let col = 0; col <= tl.nativeCol; col++) {
                let colWidth = worksheetStyle.columns && worksheetStyle.columns[col]?.width*8 || 72;
                // console.log("colWidth:",col,tl.col,colWidth)
                if(col<tl.nativeCol){// 前置列
                  imgLeft += colWidth
                }else if(col==tl.nativeCol){// 起始列
                  let strWidth = tl.nativeColOff / 914400 * 96
                  // console.log("strWidth:",strWidth)
                  imgLeft += strWidth
                  totalWidth += colWidth - strWidth;
                }else if(col>=tl.nativeCol){// 结束列
                  let endWidth = tl.nativeColOff / 914400 * 96
                  // console.log("endWidth:",endWidth)
                  totalWidth += endWidth;
                }else{
                  totalWidth += colWidth;
                }
              }
              for (let row = 0; row <= tl.nativeRow; row++) {
                if(row > 0 && row%10===0){
                  imgTop += 2// 每十行补偿2px
                }
                // getRow 从1开始
                let rowHeight = worksheetStyle.getRow(row+1)?.height*1.3333 || 20;
                // console.log("rowHeight:",row,rowHeight)
                if(row<tl.nativeRow){// 前置行
                  imgTop += rowHeight
                }else if(row==tl.nativeRow){// 起始行
                  let strHeight = tl.nativeRowOff / 914400 * 96
                  // console.log("strHeight:",strHeight,rowHeight)
                  imgTop += strHeight
                  totalHeight += rowHeight - strHeight;
                }else if(row>=tl.nativeRow){// 结束行
                  let endHeight = tl.nativeRowOff / 914400 * 96
                  // console.log("endHeight:",endHeight)
                  totalHeight += endHeight;
                }else{
                  totalHeight += rowHeight;
                }
              }
            }

            totalWidth = image.range.ext?.width || totalWidth.toFixed(4)
            totalHeight = image.range.ext?.height || totalHeight.toFixed(4)

            console.log(`图片ID: ${image.imageId}`);
            console.log(`位置: 从 (${imgLeft.toFixed(4)}，${imgTop.toFixed(4)}) `);
            console.log(`宽：${totalWidth},高：${totalHeight}`);

            // 获取图片 Buffer 并转换为 Base64
            this.getBase64FromImageBuffer(imageRef).then(base64Image => {
              rstImages.push({
                imgLeft:imgLeft.toFixed(4),
                imgTop:imgTop.toFixed(4),
                rowIndex: image.range.tl.row,
                colIndex: image.range.tl.col,
                src: `data:image/${imageRef.extension};base64,${base64Image}`,
                imgWidth:  totalWidth,
                imgHeight: totalHeight,
              });
            })
          }
          return rstImages
        });
        // 4. 加载数据到 LuckySheet
        // window.luckysheet.loadData(luckysheetData);
        console.log('Excel 文件加载图片成功，包含工作表:', imgData);
        return imgData
      } catch (error) {
        console.error('解析 Excel 文件图片失败:', error);
        alert('解析文件图片失败: ' + error.message);
        return []
      }
    },
    // 加载远程 XLSX 文件并保持样式
    async loadExcelWithStyles(workbook,workbookStyle) {
      let luckysheetData = []
      try {
        this.sheetImages = []
        // 3. 准备 LuckySheet 数据
        luckysheetData = workbook.SheetNames.map((sheetName, index) => {
          const worksheet = workbook.Sheets[sheetName];
          const worksheetStyle = workbookStyle.worksheets[index];
          const { data, merges, styles, cellImageXYs} = this.convertExcelToLuckySheet(worksheet,worksheetStyle);
          let cellImages = {sheet:index,xys:cellImageXYs}
          this.sheetImages.push(cellImages)
          return {
            name: sheetName,
            index: index,
            order: index,
            celldata: window.luckysheet.transToCellData(data),
            config: {
              merge: merges,
              rowlen: this.getRowHeights(worksheet),
              columnlen: this.getColumnWidths(worksheet),
              borderInfo: this.getBorderInfo(worksheet,worksheetStyle),
              style: styles,
              rowhidden: this.getRowHiddens(worksheetStyle),
              colhidden: this.getColumnHiddens(worksheetStyle),
            },
            status: index === 0 ? 1 : 0
          };
        });
        // 4. 加载数据到 LuckySheet
        // window.luckysheet.loadData(luckysheetData);
        console.log('Excel 文件加载成功，包含工作表:', luckysheetData);
        return luckysheetData
      } catch (error) {
        console.error('解析 Excel 文件数据失败:', error);
        alert('解析文件数据失败: ' + error.message);
        return []
      }
    },

    // 转换 Excel 样式为 LuckySheet 格式
    convertExcelToLuckySheet(worksheet,worksheetStyle) {
      // 检查 !ref 是否存在
      if (!worksheet['!ref']) {
        console.warn("工作表为空或未定义范围！");
        worksheet['!ref'] = "A1:Z100"; // 设置默认范围
      }

      const range = XLSX.utils.decode_range(worksheet['!ref']);
      const data = [];
      const merges = [];
      const styles = {};
      const cellImageXYs = [];

      // 处理合并单元格
      if (worksheet['!merges']) {
        worksheet['!merges'].forEach(merge => {
          merges.push({
            row: [merge.s.r, merge.e.r],
            col: [merge.s.c, merge.e.c],
            r: merge.s.r,     // 起始行
            c: merge.s.c,     // 起始列
            rs: merge.e.r - merge.s.r + 1, // 行数
            cs: merge.e.c - merge.s.c + 1  // 列数
          });
        });
      }

      // 处理单元格数据和样式
      for (let r = range.s.r; r <= range.e.r; r++) {
        const rowData = [];
        for (let c = range.s.c; c <= range.e.c; c++) {
          const cellAddress = XLSX.utils.encode_cell({ r: r, c: c });
          const cell = worksheet[cellAddress];
          const cellStyle = worksheetStyle.getCell(cellAddress);

          // console.log("nijsLog56:",cellStyle)

          // 单元格值
          let value = '';
          if (cell) {
            value = cell.v !== undefined ? cell.v : '';
            // console.log("value:",value)
            if(typeof value == "string" && value.indexOf("DISPIMG")>-1){// 记录单元格图片相关信息
              const cellImageXY = {r: r,c: c,value: value}
              cellImageXYs.push(cellImageXY)
            }

            // 单元格样式
            if (cellStyle.style) {
              /*if(cellStyle.style.numFmt){
                console.log("nijsLog35:",value,cellStyle.style,typeof value,cellStyle.text)
              }*/
              const styleKey = cellAddress;
              styles[styleKey] = this.convertExcelStyle(cellStyle.style);
              if(typeof value == "string" && value.indexOf("DISPIMG")>-1){// 记录单元格图片相关信息
                // 2025.10.23 nijs 图片不增加自动换行属性
                delete styles[styleKey].tb
              }
              if(typeof value === 'string'){
                rowData.push({ v: value, m: value,ct: { fa: '@', t: 's' }, ...styles[styleKey]});
              }else{
                rowData.push({ v: value, m: value, ct: { fa: cellStyle.style.numFmt || 'General', t: typeof value },...styles[styleKey]});
              }
            } else {
              rowData.push(value);
            }
          } else {
            rowData.push(value);
          }
        }
        data.push(rowData);
      }

      return { data, merges, styles, cellImageXYs };
    },

    /**
     * 将 ExcelJS 的图片 Buffer 转换为 Base64
     */
    async getBase64FromImageBuffer(imageRef) {
      // 如果是 Node.js 环境，可以直接用 Buffer
      if (typeof Buffer !== "undefined") {
        return Buffer.from(imageRef.buffer).toString("base64");
      }
      // 浏览器环境，用 Blob 和 FileReader
      else {
        const blob = new Blob([imageRef.buffer], { type: imageRef.type });
        return new Promise((resolve) => {
          const reader = new FileReader();
          reader.onload = () => resolve(reader.result.split(",")[1]);
          reader.readAsDataURL(blob);
        });
      }
    },

    parseStyles(worksheet) {
      const styles = XLSX.utils.sheet_to_csv(worksheet, { FS: '|', RS: '\n' }); // 将工作表转换为CSV格式，便于解析样式信息
      const lines = styles.split('\n'); // 按行分割
      lines.forEach((line, index) => {
        if (index > 0) { // 第一行是标题行，忽略它
          const cells = line.split('|'); // 按分隔符分割单元格内容（默认为逗号）
          cells.forEach((cell, cellIndex) => {
            const style = XLSX.utils.format_cell(worksheet[`!${index}!${cellIndex}`]); // 获取单元格样式信息
            // console.log(`Cell ${cellIndex} in row ${index} has style:`, style); // 输出样式信息
          });
        }
      });
      // console.log("nijsLog32:",styles)
      return styles;
    },

    // 转换 Excel 样式为 LuckySheet 样式
    convertExcelStyle(excelStyle) {
      const style = {};
      // console.log("nijsLog42",excelStyle)
      // 字体
      if (excelStyle.font) {
        style.ff = excelStyle.font.name || 'Arial';
        style.fs = excelStyle.font.size || 11;
        if (excelStyle.font.bold) style.bl = 1;
        if (excelStyle.font.italic) style.it = 1;
        if (excelStyle.font.underline) style.ul = 1;
        if (excelStyle.font.color) style.fc = excelStyle.font.color.rgb || '#000000';
      }

      let htMap = {"center":0,"left":1,"right":2}
      let vtMap = {"middle":0,"top":1,"bottom":2}
      // 对齐
      if (excelStyle.alignment) {
        style.ht = htMap[excelStyle.alignment.horizontal] || 0;
        style.vt = vtMap[excelStyle.alignment.vertical] || 0;
        if (excelStyle.alignment.wrapText) style.tb = 1;
      }

      // 边框
      if (excelStyle.border) {
        style.bd = {};
        ['top', 'bottom', 'left', 'right'].forEach(side => {
          if (excelStyle.border[side]) {
            style.bd[side] = {
              style: excelStyle.border[side].style || 'thin',
              color: excelStyle.border[side].color?.rgb || '#000000'
            };
          }
        });
      }

      // 背景色
      if (excelStyle.fill) {
        style.bg = excelStyle.fill.fgColor?.rgb || '#FFFFFF';
      }

      // 数字格式
      if (excelStyle.numFmt) {
        style.fmt = excelStyle.numFmt;
      }

      return style;
    },
    // 获取行高
    getRowHeights(worksheet) {
      const rowHeights = {};
      const range = XLSX.utils.decode_range(worksheet['!ref']);

      for (let r = range.s.r; r <= range.e.r; r++) {
        const row = worksheet['!rows'] && worksheet['!rows'][r];
        if (row && row.hpt) {
          rowHeights[r] = row.hpt / 0.75; // 转换为像素
        }
      }

      return rowHeights;
    },

    // 获取列宽
    getColumnWidths(worksheet) {
      const colWidths = {};
      const range = XLSX.utils.decode_range(worksheet['!ref']);

      for (let c = range.s.c; c <= range.e.c; c++) {
        const col = worksheet['!cols'] && worksheet['!cols'][c];
        if (col && col.width) {
          colWidths[c] = col.width * 8; // 转换为像素
        }
      }
      return colWidths;
    },
    // 获取隐藏行
    getRowHiddens(worksheet) {
      const rowHiddens = {};
      for (let r = 0; r < worksheet._rows.length; r++) {
        const row = worksheet._rows[r];
        if (row && row._hidden) {
          rowHiddens[r] = 0; // 记录隐藏行
        }
      }

      return rowHiddens;
    },

    // 获取隐藏列
    getColumnHiddens(worksheet) {
      const colHiddens = {};
      for (let c = 0; c <= worksheet._columns.length; c++) {
        const col = worksheet._columns[c];
        if (col && col._hidden) {
          colHiddens[c] = 0; // 记录隐藏列
        }
      }
      return colHiddens;
    },
    // 获取边框信息
    getBorderInfo(worksheet,worksheetStyle) {
      const borderInfo = [];
      const range = XLSX.utils.decode_range(worksheet['!ref']);

      for (let r = range.s.r; r <= range.e.r; r++) {
        for (let c = range.s.c; c <= range.e.c; c++) {
          const cellAddress = XLSX.utils.encode_cell({ r: r, c: c });
          const cell = worksheet[cellAddress];
          const cellStyle = worksheetStyle.getCell(cellAddress);

          if (cellStyle && cellStyle.style && cellStyle.style.border) {
            let style = this.convertBorderStyle(cellStyle.style.border)
            borderInfo.push({
              rangeType: 'cell',
              value: {
                row: [r, r],
                col: [c, c],
                row_index: r,
                col_index: c,
                ...style
              },
            });
          }
        }
      }
      return borderInfo;
    },

    // 转换边框样式
    convertBorderStyle(borderStyle) {
      const style = {};

      let map = {top:'t',left:'l',right:'r',bottom:'b'};

      let styleMap = {thin:0,};

      ['top', 'bottom', 'left', 'right'].forEach(side => {
        if (borderStyle[side]) {
          // console.log("nijsLog27:",map[side])
          style[map[side]] = {
            style: styleMap[borderStyle[side].style] || 0,
            color: borderStyle[side].color?.rgb || '#000000'
          };
        }
      });
      return style;
    },
    async parseAllDrawingRelationships(zip) {
      const rels = {};
      let relsFolder = null;

      // 尝试这些可能的路径
      const possiblePaths = [
        'xl/drawings/_rels',
        'xl/drawings/_rels/',
        'xl/drawings/drawing1.xml.rels',
        'xl/drawings/_rels/drawing1.xml.rels',
        'xl/drawings/_rels/drawing.xml.rels'
      ];
      for (const path of possiblePaths) {
        const folder = zip.folder(path);
        if (folder && Object.keys(folder.files).length > 0) {
          // 找到有效路径
          relsFolder = folder
          break;
        }
      }
      if (!relsFolder) return rels;
      // console.log("nijsLog21:",relsFolder)
      // 遍历所有关系文件
      for (const [relativePath, file] of Object.entries(relsFolder.files)) {
        // 只处理 .rels 文件
        if (!relativePath.endsWith('.rels')) continue;
        // console.log("nijsLog22:",relativePath,file)
        try {
          const content = await file.async('text');
          const parser = new DOMParser();
          const xmlDoc = parser.parseFromString(content, 'text/xml');

          // 获取所有 Relationship 节点
          const relationships = xmlDoc.getElementsByTagName('Relationship');
          // console.log("nijsLog23:", relationships)
          for (let i = 0; i < relationships.length; i++) {
            const rel = relationships[i];
            const id = rel.getAttribute('Id');
            const type = rel.getAttribute('Type');
            const target = rel.getAttribute('Target');
            // console.log("nijsLog24:",target)
            // 提取文件名并规范化路径
            const fileName = target.split('/').pop();
            const normalizedTarget = target.replace(/^..\//, ''); // 去除开头的../
            if(target.indexOf('media')>-1){
              // 存储关系信息
              rels[id] = {
                id,
                type: type.split('/').pop(), // 只保留最后一部分，如 "image"
                fileName: fileName,
                fullPath: `xl/${normalizedTarget}`, // 完整路径，如 "xl/media/image1.png"
                sourceFile: relativePath // 来源的rels文件路径
              };
            }
          }
        } catch (error) {
          console.error(`Error parsing relationship file ${relativePath}:`, error);
        }
      }
      // console.log("nijsLog25:",rels)

      return rels;
    },
    async parseCellImages(zip, mediaFiles, drawingRels) {
      const images = [];
      const sheetPath = `xl/cellimages.xml`;
      const sheetFile = zip.file(sheetPath);

      if (!sheetFile) return images;
      // console.log("nijsLog11:",sheetFile)
      try {
        console.log("nijsLog28:",mediaFiles,drawingRels)

        const content = await sheetFile.async('text');
        const xmlDoc = new DOMParser().parseFromString(content, 'text/xml');
        // console.log("nijsLog07:",xmlDoc)

        // 查找其他可能的图片引用
        let cellImages = xmlDoc.getElementsByTagName('etc:cellImages');
        if(cellImages.length>0){
          cellImages = cellImages[0].getElementsByTagName('etc:cellImage');
        }
        // console.log("nijsLog09:",cellImages)
        for (let j = 0; j < cellImages.length; j++) {
          const cellImage = cellImages[j];
          // console.log("nijsLog11:",cellImage)
          const pic = cellImage.getElementsByTagName('xdr:pic')[0];
          // console.log("nijsLog12:",pic)
          const nvPicPr = pic.getElementsByTagName('xdr:nvPicPr')[0];
          // console.log("nijsLog13:",nvPicPr)
          const cNvPr = nvPicPr.getElementsByTagName('xdr:cNvPr')[0];
          // console.log("nijsLog131:",cNvPr)
          const name = cNvPr.getAttribute('name');// 单元格函数中的ID_XXX
          // console.log("nijsLog1311:",name)
          const blipFill = pic.getElementsByTagName('xdr:blipFill')[0];
          // console.log("nijsLog14:",blipFill)
          const blip = blipFill.getElementsByTagName('a:blip')[0];
          // console.log("nijsLog141:",blip)
          const embed = blip.getAttribute('r:embed');// 关联关系图片获取到的id属性
          // console.log("nijsLog1411:",embed)
          // const spPr = pic.getElementsByTagName('xdr:spPr')[0];
          // console.log("nijsLog15:",spPr)
          // console.log("nijsLog36:",name,embed)
          let drawingRel = drawingRels[embed]
          // console.log("nijsLog37:",drawingRel)
          let mediaFile = mediaFiles.find(item=>item.name==drawingRel.fullPath)
          // console.log("nijsLog38:",mediaFile)

          if (drawingRel) {
            images.push({
              id: name,
              fileName: mediaFile.name,
              url: mediaFile.url,
              embed: embed,
            });
          }
        }
      } catch (error) {
        console.error(`Error parsing images :`, error);
      }

      return images;
    },
  },
};
</script>
<style lang="css" scoped>
.luckysheet-content {
  margin: 0px;
  padding: 0px;
  width: 100%;
  height: calc(100vh - 30px);
  left: 0px;
  top: 40px;
  bottom: 0px;
}
</style>
